package com.bt.lms.ui.page.sys.user.action;

import com.bt.lms.constants.BOConstant;
import com.bt.lms.constants.SysBizTypeConstant;
import com.bt.lms.entity.User;
import com.bt.lms.entity.page.Page;
import com.bt.lms.network.msg.RespMsg;
import com.bt.lms.ui.page.sys.utils.ArrayUtils;
import com.bt.lms.ui.page.sys.utils.NetWorkUtils;
import com.bt.lms.ui.vo.PageSkipInfo;
import com.bt.lms.ui.page.sys.utils.Encode;
import com.bt.lms.network.msg.ReqMsg;
import com.bt.lms.ui.page.sys.ServerInfo;
import com.bt.lms.ui.page.sys.user.PageCompile;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;

/**
 * 用户编辑界面的保存按钮事件
 */
public class UCSaveBtnAction implements EventHandler<ActionEvent> {

    /**
     * 界面跳转数据
     */
    private final PageSkipInfo pageSkipInfo;

    /**
     * 当前用户id
     */
    private final Long id;

    /**
     * 构造保存按钮事件
     *
     * @param pageSkipInfo 界面跳转数据
     * @param id           当前用户id
     */
    public UCSaveBtnAction(PageSkipInfo pageSkipInfo, Long id) {
        this.pageSkipInfo = pageSkipInfo;
        this.id = id;
    }

    /**
     * 保存用户信息（编辑界面）
     *
     * @param event the event which occurred
     */
    @Override
    public void handle(ActionEvent event) {

        //1.获取用户输入
        User user = getInput();
        //2.验证用户输入
        String hint = verifyInput(user);
        //3.组装消息包
        if (null == hint) {
            //验证通过
            //3.1发送请求
            //3.1.1 组装消息包
            //验证通过
            ReqMsg reqMsg = Encode.encodeToMsg(user, SysBizTypeConstant.USER_EDIT);
            byte[] bytes = reqMsg.toBytes();
            //3.1.2 组网
            Socket socket = packageNet();
            try {
                OutputStream out = socket.getOutputStream();
                //3.1.3 发网，返回结果
                boolean result = sendMes(out, bytes);
                //判断是否发送成功
                if (result) {
                    try {
                        //3.2 接收响应
                        InputStream in = socket.getInputStream();
                        //3.2.1 接受响应
                        List<byte[]> bufS = NetWorkUtils.receive(in);
                        //3.2.2 处理结果
                        byte[] respBytes = ArrayUtils.joinBytes(bufS);
                        //3.2.3 转消息
                        RespMsg respMsg = RespMsg.toRespMsg(respBytes);
                        //3.2.4 比较状态
                        short status = respMsg.getStatus();
                        if (status == RespMsg.NETWORK_STATUS_NORMAL) {
                            //关流
                            in.close();
                            out.close();
                            socket.close();
                            //成功发送，程序结束
                            finish();
                        } else {
                            String failStr = "未能保存成功，请稍候重试。";
                            hintFrame(failStr);//提示框
                        }
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    //发送失败
                    String hintStr = "网络异常，请检查网络或联系客服。";
                    hintFrame(hintStr);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        } else {
            //提示框
            hintFrame(hint);
        }

    }

    /**
     * 程序结束
     */
    private void finish() {

        //提示弹窗
        Alert alert = new Alert(Alert.AlertType.INFORMATION);

        //保存提示
        alert.setTitle("保存");
        alert.setHeaderText(null);
        alert.setContentText("保存成功");
        alert.showAndWait();

        //界面跳转
        NetWorkUtils.reqUserPagingPage(pageSkipInfo,new Page<>());

    }

    /**
     * 提示框
     *
     * @param hint 提示文本
     */
    private void hintFrame(String hint) {

        //弹窗提示
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("失败");
        alert.setHeaderText(null);
        alert.setContentText(hint);
        alert.showAndWait();
    }

    /**
     * 发网
     *
     * @param out 输出流
     * @param bytes  要发送的数据
     * @return 发送结果
     */
    private boolean sendMes(OutputStream out, byte[] bytes) {

        //发送
        try {
            out.write(bytes);
            out.flush();
            return true;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 组网
     *
     * @return 网
     */
    private Socket packageNet() {

        String ip = ServerInfo.IP;
        Integer port = ServerInfo.PORT;

        try {
            return new Socket(ip, port);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 验证用户输入
     *
     * @param user 用户输入
     * @return 验证结果
     */
    private String verifyInput(User user) {

        String text = "";

        //验证账号（邮箱） 必填 文本 64位以下邮箱
        String accountNumber = user.getAccountNumber();
        if ("".equals(accountNumber)) {
            //为空
            text += "账号不可为空，请输入邮箱.\t\n";
        } else {
            //验证邮箱格式   必须包含@ 和 .    且.在@之后
            int i = accountNumber.lastIndexOf("@");
            int j = accountNumber.lastIndexOf(".");
            if (i > j) {
                //邮箱格式不通过
                text += "邮箱格式不正确，请重新输入.\t\n";
            } else {
                int length = accountNumber.length();
                if (length > 64) {
                    //长度过长
                    text += "邮箱过长，请重新输入.\t\n";
                }
            }

        }

        //验证用户名 必填 文本 小
        String name = user.getName();
        if ("".equals(name)) {
            //没有姓名
            text += "姓名不可空，输入姓名。\t\n";
        } else {
            //姓名过长
            int length = name.length();
            if (length > 32) {
                //长度大于32
                text += "姓名过长，请重新输入。\t\n";
            }
        }

        //验证证件号
        Integer codeType = user.getCodeType();//证件类型
        String code = user.getCode();//证件号码
        String s = idVerify(codeType, code);//验证证件号码
        text += s;

        //验证所属单位 必填 文本 小
        String unit = user.getUnit();
        if ("".equals(unit)) {
            //为空
            text += "所属单位为空，请重新输入。\t\n";
        } else {
            //单位过长
            int length = unit.length();
            if (length > 32) {
                text += "所属单位过长，请重新输入。\t\n";
            }
        }
        //验证移动电话
        String mobilePhone = user.getMobilePhone();
        if ("".equals(mobilePhone)) {
            //没有电话
            text += "移动电话为空，请重新输入。\t\n";
        } else {

            //纯数字
            try {
                //是否是数字
                Long.valueOf(mobilePhone);
                //电话过长
                int length = mobilePhone.length();
                if (length > 32) {
                    text += "电话过长，请重新输入\t\n";
                }
            } catch (NumberFormatException e) {
                text += "电话需要是纯数字，请重新输入\t\n";
            }
        }

        if ("".equals(text))
            return null;
        else
            return text;
    }

    /**
     * 验证证件
     *
     * @param codeType 证件类型
     * @param code     证件号码
     */
    private String idVerify(Integer codeType, String code) {
        //提示文本
        String hint = "";
        if (codeType == 1) {
            //身份证 18数字，1数字或字母x  id  17位数字，最后一位数字或字母 总长18
            int idLen = code.length();
            if (idLen != 18) {
                //不等于18
                hint += "长度不对，请输入正确的身份证号码。\t\n";
            } else {
                try {
                    String substring = code.substring(0, 17);
                    Long.parseLong(substring);
                    char c = code.charAt(17);
                    if (!(c >= '0' && c <= '9')) {
                        if (c != 'X' && c != 'x') {
                            hint += "格式错误，请输入正确的身份证号码（如有英文，请大写）。\t\n";
                        }
                    }
                } catch (NumberFormatException e) {
                    hint += "格式错误，请输入正确的身份证号码（如有英文，请大写）。\t\n";
                }
            }
        } else if (codeType == 2) {
            //士官证  沈字第0100000号   第一位汉字，后续固定：字第*******号
            //总长11位
            int idLen = code.length();
            if (idLen != 11) {
                //长度不是11位
                hint += "长度错误，请输入正确的士官证号码。\t\n";
            } else {
                //汉字正则表达式
                String reg = "[\\u4e00-\\u9fa5]";
                //前三位
                char c = code.charAt(0);
                boolean start = String.valueOf(c).matches(reg);//开头是否是汉字
                boolean centre = code.startsWith("字第", 1); //二三位是否是字第
                //中间七位数字
                String number = code.substring(3, 10);
                //最后一位汉字
                boolean finish = code.endsWith("号");

                if (!start) {
                    //不是汉字开头
                    hint += "格式错误，请输入正确的士官证号码。\t\n";
                } else if (!centre) {
                    //二三位不是”字第“
                    hint += "格式错误，请输入正确的士官证号码。\t\n";
                } else if (!finish) {
                    //结尾不是“”
                    try {
                        Integer.parseInt(number);
                    } catch (NumberFormatException e) {
                        //中间7位不是数字
                        hint += "格式错误，请输入正确的士官证号码。\t\n";
                    }
                }
            }

        } else if (codeType == 3) {
            //学生证
            //暂时无法判断，每个学校的学生证格式不一致
            //判断是否全为数字
            try {
                Long.parseLong(code);
            } catch (NumberFormatException e) {
                hint += "格式错误，请输入正确的学生证号码。\t\n";
            }
        } else if (codeType == 4) {
            //驾驶证  12位 前两位省  后两位市  纯数字
            int idLen = code.length();
            if (idLen != 12) {
                hint += "长度错误，请输入正确的驾驶证号码。\t\n";
            } else {
                try {
                    Long.parseLong(code);
                } catch (NumberFormatException e) {
                    hint += "格式错误，请输入正确的驾驶证号码。\t\n";
                }
            }
        } else if (codeType == 5) {
            //护照 长度9位
            int idLen = code.length();
            if (idLen != 9) {
                hint += "格式错误，请输入正确的护照号码。\t\n";
            }
        } else if (codeType == 6) {
            //港澳通行证 9位 第一位C 后8位数字
            int idLen = code.length();
            if (idLen != 9) {
                hint += "长度错误，请输入正确的港澳通行证号码。\t\n";
            } else {
                boolean c = code.startsWith("C");
                if (!c) {
                    hint += "格式错误，请输入正确的港澳通行证号码。\t\n";
                } else {
                    String substring = code.substring(1);
                    try {
                        Long.parseLong(substring);
                    } catch (NumberFormatException e) {
                        hint += "格式错误，请输入正确的港澳通行证号码。\t\n";
                    }
                }
            }
        }
        return hint;
    }

    /**
     * 获取用户输入
     *
     * @return 编辑用户信息VO
     */
    private User getInput() {

        //要返回的对象
        User user = new User();
        //id
        user.setId(id);

        //大容器
        Pane pane = pageSkipInfo.getPane();
        //获取组件及组件内容
        //账号（邮箱）
        TextField emailTF = (TextField) pane.lookup("#" + PageCompile.EMAIL_TF);
        String email = emailTF.getText().trim();
        user.setAccountNumber(email);

        //用户名
        TextField nameTF = (TextField) pane.lookup("#" + PageCompile.NAME_TF);
        String name = nameTF.getText().trim();
        user.setName(name);

        //证件类型
        int codeType = -1;
        ChoiceBox codeTypeCB = (ChoiceBox) pane.lookup("#" + PageCompile.ID_TYPE_CB);
        String value = (String) codeTypeCB.getValue();
        switch (value) {
            case "身份证":
                codeType = 1;
                break;
            case "士官证":
                codeType = 2;
                break;
            case "学生证":
                codeType = 3;
                break;
            case "驾驶证":
                codeType = 4;
                break;
            case "护照":
                codeType = 5;
                break;
            case "港澳通行证":
                codeType = 6;
                break;
        }
        user.setCodeType(codeType);

        //证件号码
        TextField codeTF = (TextField) pane.lookup("#" + PageCompile.ID_TF);
        String code = codeTF.getText().trim();
        user.setCode(code);

        //所属单位
        TextField unitTF = (TextField) pane.lookup("#" + PageCompile.UNIT_TF);
        String unit = unitTF.getText().trim();
        user.setUnit(unit);

        //移动电话
        TextField phoneTF = (TextField) pane.lookup("#" + PageCompile.PHONE_TF);
        String phone = phoneTF.getText().trim();
        user.setMobilePhone(phone);

        return user;
    }
}
